import is.glif.fenius.ws.draft.gen.ReservationParams;
import is.glif.fenius.ws.draft.gen.Avp;
import is.glif.fenius.ws.draft.gen.AvpSeq;
import is.glif.fenius.ws.draft.gen.Status;

import javax.xml.datatype.XMLGregorianCalendar;

import java.util.ArrayList;
import java.util.List;
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class FeniusDraftList extends HttpServlet {
    static public final long serialVersionUID = 01010101L;
    static public Thread[] threads = null;
    // static public Hashtable<String, ReservationParams> lists = null;
    static public Hashtable<String, Hashtable<String, ReservationParams>> dlists = null;
    static public Hashtable<String, String> status = null;
    static public long INTERVAL = 5000;
    static public int DISPLAY_TIME_MINUTE = 10;

    final static String STATUS_UP = "up";
    final static String STATUS_DOWN = "down";
    final static String STATUS_UNKNOWN = "checking";

    static {
	TimeZone.setDefault(FeniusDraftCreate.timezone);
	// lists = new Hashtable<String, ReservationParams>();
	dlists = new Hashtable<String, Hashtable<String, ReservationParams>>();
	status = new Hashtable<String, String>();

	int size = FeniusDraftCreate.clients.size();
	threads = new Thread[size];
	int i = 0;

	for(Enumeration e = FeniusDraftCreate.clients.keys(); e.hasMoreElements();){
	    final String domain = (String) e.nextElement();
	    final FeniusDraftClient client = FeniusDraftCreate.clients.get(domain);

	    threads[i] = new Thread(new Runnable(){
		    public void run() 
		    {
			Hashtable<String, ReservationParams> lists = null;

			while(true) {
			    try {
				Thread.sleep(INTERVAL);
				System.err.println
				    ("=========== list start:" + client.urlname);
				    
				lists = new Hashtable<String, ReservationParams>();
				List<ReservationParams> rps = client.doList();

				if (rps != null && rps.size() != 0) {
				    int size = rps.size();
				    for (int k = 0; k < size; k++) {
					ReservationParams rp = rps.get(k);
					String id = rp.getReservationId();
					if (id != null) {
					    lists.put(id, rp);
					}
				    }
				}
				dlists.put(domain, lists);

				status.put(domain, STATUS_UP);
				System.err.println
				    ("=========== list end:" + client.urlname);
			    } catch (Exception ex) {
				status.put(domain, STATUS_DOWN);
				System.err.println
				    ("=========== Exception in list to " +
				     client.urlname + ".");
				System.err.println(ex.toString());
				dlists.put(domain, lists);
			    }
			}
		    }
		});
	    threads[i].start();
	    i++;
	}
    }

    public FeniusDraftList() 
    {
    }

    public static synchronized String getString(Calendar c) {
	if (c == null) return null;

	String s = (c.get(Calendar.MONTH)+1)
	    + "/" + c.get(Calendar.DAY_OF_MONTH)
	    + " " + c.get(Calendar.HOUR_OF_DAY)
	    + ":" + c.get(Calendar.MINUTE)
	    + ":" + c.get(Calendar.SECOND)
	    + "(" + FeniusDraftCreate.timezone.getID() + ")";
	return s;
    }

    public static Calendar getCalendar()
    {
	Calendar calendar = Calendar.getInstance();
	calendar.setTime(new Date());
	calendar.set(Calendar.MILLISECOND, 0);
	return calendar;
    }

    private String head1A =
	"<html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\"><script type=\"text/javascript\"><!--\n function refresh() { location.href=\"/servlets/FeniusDraftList\";} \n --> </script> <link rel=\"stylesheet\" type=\"text/css\" href=\"/servlets/fenius.css\"><title>Fenius Reservation Monitor</title><body onload=\"setTimeout('location.reload();', ";
    private String head1B =
	"<html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\"><script type=\"text/javascript\"><!--\n function refresh() { location.href=\"/servlets/FeniusDraftList\";} \n --> </script> <link rel=\"stylesheet\" type=\"text/css\" href=\"/servlets/fenius.css\"><title>Fenius Reservation Monitor</title><body onload=\"setTimeout('refresh();', ";
    private String head2 = ");\">";
    private String tail = "</body></html>\n";
    private int refresh_time = 5;

    public void doGet(HttpServletRequest request,
                      HttpServletResponse response)
        throws IOException, ServletException
    {
	System.err.println("=========== doGet list start now\n");
	Calendar c = getCalendar();
	String s = "";
	String do_cancel = request.getParameter("reset");
	System.err.println("do_cancel=" + do_cancel);
	if (do_cancel != null && do_cancel.equals("RESET")) {
	    dlists.clear();
	    s = head1B + (1 * 1000) + head2;
	} else {
	    s = head1A + (refresh_time * 1000) + head2;
	}

	s += "<H1 align=center>Fenius Reservation Monitor</H1>\n";
	s += "<form action=\"FeniusDraftList\" method=POST>";
	s += "<table width=\"96%\" align=\"center\" border=\"0\" cellpadding=\"5\"><div align=\"right\">";

	s += "<tr bgcolor=\"#C0C0C0\" align=\"center\">\n";
	for(Enumeration e = FeniusDraftCreate.clients.keys(); e.hasMoreElements();){
	    String domain = (String) e.nextElement();
	    FeniusDraftDomain d = FeniusDraftCreate.domains.get(domain);
	    String display = d.getDisplayName();
	    s += "<th>" + display + "</th>\n";
	}
	s += "<th> Reset Information </th>\n";
	s += "<th> Current Time </th>\n";
	s += "</tr><tr align=\"center\">\n";
	for(Enumeration e = FeniusDraftCreate.clients.keys(); e.hasMoreElements();){
	    String domain = (String) e.nextElement();
	    String up = status.get(domain);
	    if (up == null) up = STATUS_UNKNOWN;
	    s += "<td>" + up + "</td>\n";
	}
	s += "<td> <input type=submit name=reset value=RESET /> </td>\n";
	s += "<td>" + getString(c) + "</td>\n";
	s += "</table>\n";

	s += "<BR>\n";
	
	s += "<table width=\"96%\" align=\"center\" border=\"0\" cellpadding=\"5\">";
	s += "<tr bgcolor=\"#C0C0C0\"><th>Reservation<BR>ID</th><th>Terminal<BR>Point</th><th>Terminal<BR>Point</th><th>Activate<BR>Time</th><th>Duration<BR>(sec)</th><th>BW<BR>(Mbps)</th><th>VLAN</th><th>Status</th></tr>\n";

	boolean color = false;
	System.err.println("=========== doGet list size:" + dlists.size());

	for(Enumeration de = dlists.keys(); de.hasMoreElements();){
	    String domain = (String) de.nextElement();
	    Hashtable<String, ReservationParams> lists = dlists.get(domain);
	    if (lists == null) continue;

	    for(Enumeration e = lists.elements(); e.hasMoreElements();){
		ReservationParams rp = (ReservationParams) e.nextElement();

		XMLGregorianCalendar sgc = 
		    rp.getEndtoendParams().getTimeParams().getScheduledStartTime();
		Long smsec = sgc.toGregorianCalendar().getTimeInMillis();
		// gc.setTimezone(FeniusDraftCreate.timezone.getRawOffset()/1000/60);
		XMLGregorianCalendar egc = 
		    rp.getEndtoendParams().getTimeParams().getScheduledEndTime();
		Long emsec = egc.toGregorianCalendar().getTimeInMillis();
		Long dmsec = (emsec - smsec) / 1000;

		Calendar ec = Calendar.getInstance();
		ec.setTime(new Date(emsec));
		ec.add(Calendar.MINUTE, DISPLAY_TIME_MINUTE);
		if (c.after(ec)) continue;

		if (false) helper(rp);

		if (color) {
		    s += "<tr bgcolor=\"#00FFFF\">";
		    color = false;
		} else {
		    s += "<tr>";
		    color = true;
		}
		    
		s += "<td>" + rp.getReservationId() + "</td>";
		// s += "<td>" + rp.getEndpoints().getA() + "</td>";
		// s += "<td>" + rp.getEndpoints().getZ() + "</td>";
		s += "<td>" + FeniusDraftCreate.endpoint2alias.get(rp.getEndpoints().getA()) + "</td>";
		s += "<td>" + FeniusDraftCreate.endpoint2alias.get(rp.getEndpoints().getZ()) + "</td>";
		s += "<td>" + sgc.toString() + "</td>";
		s += "<td>" + dmsec + "</td>";
		s += "<td>" + rp.getEndtoendParams().getBandwidth() + "</td>";
	    
		AvpSeq seq = rp.getEndtoendParams().getAdhocParams();
		String vlan = "0";
		for (Avp avp : seq.getAvp()) {
		    if (avp.getAttrName().equals("eth.vlan")) {
			vlan = avp.getAttrVal();
		    }
		}
		s += "<td>" + vlan + "</td>";
	    
	    
		String status = rp.getEndtoendParams().getStatus().toString();
		s += "<td>" + status + "</td>";
		s += "</tr>\n";
	    }
	}
	s += "</table>\n";
	s += "</form>\n";
	s += tail;

	response.setContentType("text/html");

        PrintWriter out = response.getWriter();
        out.println(s);
	System.err.println("=========== doGet list end \n");
    }

    public void doPost(HttpServletRequest request,
                      HttpServletResponse response)
        throws IOException, ServletException
    {
        doGet(request, response);
    }

    public void helper(ReservationParams rp)
    {
	String apoint = rp.getEndpoints().getA();
	FeniusDraftDomain d = FeniusDraftCreate.endpoint2domain.get(apoint);
	if (d == null) return;
	String name = d.getName();

	if(name.equals("hpdm.net")) {
	    statusHelper(rp);
	    endpointHelper(rp);
	} else if (name.equals("kreonet.re.kr")) {
	    statusHelper(rp);
	}
    }

    public void statusHelper(ReservationParams rp)
    {
	XMLGregorianCalendar sgc = 
	    rp.getEndtoendParams().getTimeParams().getScheduledStartTime();
	Long smsec = sgc.toGregorianCalendar().getTimeInMillis();
	Calendar sc = Calendar.getInstance();
	sc.setTime(new Date(smsec));

	XMLGregorianCalendar egc = 
	    rp.getEndtoendParams().getTimeParams().getScheduledEndTime();
	Long emsec = egc.toGregorianCalendar().getTimeInMillis();
	Calendar ec = Calendar.getInstance();
	ec.setTime(new Date(emsec));

	Calendar c = getCalendar();
	if (c.after(sc)) 
	    rp.getEndtoendParams().setStatus(Status.ACTIVE);
	if (c.after(ec)) 
	    rp.getEndtoendParams().setStatus(Status.FINISHED);
    }

    public void endpointHelper(ReservationParams rp)
    {
	String apoint = rp.getEndpoints().getA();
	String zpoint = rp.getEndpoints().getZ();

	String t = "10.0.1.1";
	if (t.equals(apoint)) rp.getEndpoints().setA("net.hpdm:synchromedia:be/2");
	if (t.equals(zpoint)) rp.getEndpoints().setZ("net.hpdm:synchromedia:be/2");

	t = "10.0.1.2";
	if (t.equals(apoint)) rp.getEndpoints().setA("net.hpdm:synchromedia:ue/clusterSite");
	if (t.equals(zpoint)) rp.getEndpoints().setZ("net.hpdm:synchromedia:ue/clusterSite");

	t = "10.0.1.3";
	if (t.equals(apoint)) rp.getEndpoints().setA("net.hpdm:synchromedia:ue/displayCam");
	if (t.equals(zpoint)) rp.getEndpoints().setZ("net.hpdm:synchromedia:ue/displayCam");

	t = "10.0.1.4";
	if (t.equals(apoint)) rp.getEndpoints().setA("net.hpdm:synchromedia:ue/videoCam");
	if (t.equals(zpoint)) rp.getEndpoints().setZ("net.hpdm:synchromedia:ue/videoCam");
    }

    static public void main(String[] args)
    {
	FeniusDraftList fdl = new FeniusDraftList();
    }
}
